package com.gitee.feizns.menu.boot;

import com.gitee.feizns.menu.intercetor.MenuEnumVerificationInterceptor;
import com.gitee.feizns.menu.intercetor.VerificationHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Arrays;
import java.util.function.IntFunction;

/**
 * @author feizns
 * @since 2019/5/10
 */
@Order
@Configuration
@ConditionalOnWebApplication
public class MenuAutoConfiguration implements WebMvcConfigurer {

    private MenuProperties properties;

    public MenuAutoConfiguration(MenuProperties properties) {
        this.properties = properties;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(menuHandlerInterceptor());
    }

    private HandlerInterceptor menuHandlerInterceptor() {
        VerificationHandler[] handlers = getInstances(VerificationHandler[]::new, properties.getHandlerClass());
        MenuEnumVerificationInterceptor<?> interceptor
                = new MenuEnumVerificationInterceptor<>(properties.getAnnotation(), handlers);
        return interceptor;
    }

    private static final VerificationHandler[] getInstances(IntFunction<VerificationHandler[]> supplier, Class<? extends VerificationHandler>... classes) {
        return Arrays.stream(classes).map(MenuAutoConfiguration::getInstance).toArray(supplier);
    }

    private static final <T> T getInstance(Class<T> clz) {
        try {
            return clz.newInstance();
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

}